package com.tencent.bk.utils.blueking.tools;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Pattern;

@SuppressWarnings("unused")
public class StringConverters {

    private final static Logger logger = LoggerFactory.getLogger(StringConverters.class);

    public final static String DATE_FORMAT_FULL = "yyyy-MM-dd HH:mm:ss";
    public final static String DATE_FORMAT_YEAR_MONTH_DAY = "yyyy-MM-dd";

    /**
     * 将传入的参数转换为Date类型并返回
     *
     * @param convertString 需要转换的参数
     * @return Converted Date Object.
     */
    public static Date ToDateOnly(String convertString) {
        return ToDatePattern(convertString, DATE_FORMAT_YEAR_MONTH_DAY, "");
    }

    public static Date ToDateTime(String convertString) {
        return ToDatePattern(convertString, DATE_FORMAT_FULL, "");
    }

    /**
     * 将传入的参数转换为Date类型并返回
     *
     * @param convertString 需要转换的参数
     * @param pattern       日期转换格式匹配
     * @return Converted Date Object.
     */
    public static Date ToDatePattern(String convertString, String pattern) {
        return ToDatePattern(convertString, pattern, "");
    }

    /**
     * 将传入的参数转换为Date类型并返回
     *
     * @param convertString 需要转换的参数
     * @param pattern       日期转换格式匹配
     * @param paramDesc     需要转换的参数说明(作为日志补充)
     * @return Converted Date Object.
     */
    public static Date ToDatePattern(String convertString, String pattern, String paramDesc) {

        pattern = CommonSugar.getStringDefault(pattern, DATE_FORMAT_FULL);

        Date result = null;
        if (!StringUtils.isEmpty(convertString)) {
            try {
                SimpleDateFormat sdf = new SimpleDateFormat(pattern);
                sdf.setLenient(false);
                result = sdf.parse(convertString);
                logger.debug("转换成功[String-Date]，输入参数[{}]为[{}]", paramDesc, convertString);
            } catch (Exception ex) {
                logger.error("转换失败[String-Date]，输入参数[{}]为[{}]", paramDesc, convertString);
            }
        } else {
            logger.debug("转换失败[String-Date]，输入参数[{}]为[{}]", paramDesc, convertString);
        }
        return result;
    }


    /**
     * 将传入的参数转换为Integer类型并返回
     *
     * @param convertString 需要转换的参数
     * @return Converted Integer Object.
     */
    public static Integer ToInteger(String convertString) {
        return ToInteger(convertString, "字符串");
    }

    /**
     * 将传入的参数转换为Integer类型并返回
     *
     * @param convertString 需要转换的参数
     * @param paramDesc     需要转换的参数说明(作为日志补充)
     * @return Converted Integer Object.
     */
    public static Integer ToInteger(String convertString, String paramDesc) {

        Integer result = null;
        if (!StringUtils.isEmpty(convertString)) {
            try {
                result = Integer.parseInt(convertString);
                logger.debug("转换成功[String-Integer]，输入参数[{}]为[{}]", paramDesc, convertString);
            } catch (Exception ex) {
                logger.error("转换失败[String-Integer]，输入参数[{}]为[{}]", paramDesc, convertString);
            }
        } else {
            logger.debug("转换失败[String-Integer]，输入参数[{}]为[{}]", paramDesc, convertString);
        }
        return result;
    }

    /**
     * Object转BigDecimal
     *
     * @param value
     * @return
     */
    public static BigDecimal ToBigDecimal(Object value) {
        BigDecimal ret = BigDecimal.ZERO;
        if (value != null) {
            if (value instanceof BigDecimal) {
                ret = (BigDecimal) value;
            } else if (value instanceof String) {
                ret = new BigDecimal((String) value);
            } else if (value instanceof Integer) {
                ret = new BigDecimal((Integer) value);
            } else if (value instanceof Number) {
                ret = new BigDecimal(((Number) value).doubleValue());
            } else {
                throw new ClassCastException("Not possible to coerce [" + value + "] from class " + value.getClass() + " into a BigDecimal.");
            }
        }
        return ret;
    }


    /**
     * 将传入的参数转换为Long类型并返回
     *
     * @param convertString 需要转换的参数
     * @return Converted Long Object.
     */
    public static Long ToLong(String convertString) {
        return ToLong(convertString, "字符串");
    }

    /**
     * 将传入的参数转换为Long类型并返回
     *
     * @param convertString 需要转换的参数
     * @param paramDesc     需要转换的参数说明(作为日志补充)
     * @return Converted Long Object.
     */
    public static Long ToLong(String convertString, String paramDesc) {

        Long result = null;
        if (!StringUtils.isEmpty(convertString)) {
            try {
                result = Long.parseLong(convertString);
                logger.debug("转换成功[String-Long]，输入参数[{}]为[{}]", paramDesc, convertString);
            } catch (Exception ex) {
                logger.error("转换失败[String-Long]，输入参数[{}]为[{}]", paramDesc, convertString);
            }
        } else {
            logger.debug("转换失败[String-Long]，输入参数[{}]为[{}]", paramDesc, convertString);
        }

        return result;
    }

    /**
     * 将传入的参数转换为Float类型并返回
     *
     * @param convertString 需要转换的参数
     * @return Converted Float Object.
     */
    public static Float ToFloat(String convertString) {
        return ToFloat(convertString, "字符串");
    }

    /**
     * 将传入的参数转换为Float类型并返回
     *
     * @param convertString 需要转换的参数
     * @param paramDesc     需要转换的参数说明(作为日志补充)
     * @return Converted Float Object.
     */
    public static Float ToFloat(String convertString, String paramDesc) {

        Float result = null;
        if (!StringUtils.isEmpty(convertString)) {
            try {
                result = Float.parseFloat(convertString);
                logger.debug("转换成功[String-Double]，输入参数[{}]为[{}]", paramDesc, convertString);
            } catch (Exception ex) {
                logger.error("转换失败[String-Double]，输入参数[{}]为[{}]", paramDesc, convertString);
            }
        } else {
            logger.debug("转换失败[String-Double]，输入参数[{}]为[{}]", paramDesc, convertString);
        }

        return result;
    }

    /**
     * 将传入的参数转换为Double类型并返回
     *
     * @param convertString 需要转换的参数
     * @return Converted Double Object.
     */
    public static Double ToDouble(String convertString) {
        return ToDouble(convertString, "字符串");
    }

    /**
     * 将传入的参数转换为Double类型并返回
     *
     * @param convertString 需要转换的参数
     * @param paramDesc     需要转换的参数说明(作为日志补充)
     * @return Converted Double Object.
     */
    public static Double ToDouble(String convertString, String paramDesc) {

        Double result = null;
        if (!StringUtils.isEmpty(convertString)) {
            try {
                result = Double.parseDouble(convertString);
                logger.debug("转换成功[String-Double]，输入参数[{}]为[{}]", paramDesc, convertString);
            } catch (Exception ex) {
                logger.error("转换失败[String-Double]，输入参数[{}]为[{}]", paramDesc, convertString);
            }
        } else {
            logger.debug("转换失败[String-Double]，输入参数[{}]为[{}]", paramDesc, convertString);
        }

        return result;
    }

    public static String objectToString(Object object) {
        try {
            return object.toString();
        } catch (Exception e) {
        }
        return "";
    }

    public static boolean isNumeric(String str) {
        Pattern pattern = Pattern.compile("^[-\\+]?[\\d]*$");
        return pattern.matcher(str).matches();
    }

    public ConcurrentHashMap<String, Object> objectToConcurrentMap(Object obj) throws Exception {
        if (obj == null) {
            return null;
        }
        ConcurrentHashMap<String, Object> map = new ConcurrentHashMap<>();
        Field[] declaredFields = obj.getClass().getDeclaredFields();
        for (Field field : declaredFields) {
            field.setAccessible(true);
            Object v = field.get(obj);
            if (v != null) {
                map.put(field.getName(), v);
            }
        }

        return map;
    }

    public static Integer getWeekDay(Date today) {
        Calendar c = Calendar.getInstance();
        c.setTime(DateTimeUtils.addDayOfMonth(today,-1));
        return c.get(Calendar.DAY_OF_WEEK);
    }

    /*
     * 将时间戳转换为时间
     */
    public static String stampToDate(String s){
        String res;
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        long lt = new Long(s);
        Date date = new Date(lt);
        res = simpleDateFormat.format(date);
        return res;
    }

    /*
     * 将时间转换为时间戳
     */
    public static String dateToStamp(String s){
        try {
            String res;
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            Date date = simpleDateFormat.parse(s);
            long ts = date.getTime();
            res = String.valueOf(ts/1000);
            return res;
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return "";
    }
}
